﻿using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using System.Threading;
using System.Windows.Threading;

namespace WpfAppTestMyVideoCapture
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        MyVideo.MyVideoCapture cap = null;
        public MainWindow()
        {
            InitializeComponent();
            this.ContentRendered += MainWindow_ContentRendered;
            this.Closing += MainWindow_Closing;
        }

        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            cap.Dispose();
            isGrabimg = false;
        }

        private void MainWindow_ContentRendered(object sender, EventArgs e)
        {
            try
            {
                cap = new MyVideo.MyVideoCapture();              
            }
            catch (Exception ex)
            {
                lblStatus.Content = string.Format("初始化{0} 异常 ", ex.Message);
            }
        }


        private void btnOpen_Click(object sender, RoutedEventArgs e)
        {
            if(cap.IsOpened)
            {
                cap.Close();
            }
            try
            {
                
                cap._capIndex =int.Parse(txtIndex.Text.Trim());
                cap._desiredWidth = int.Parse(txtWidth.Text.Trim());
                cap._desiredHeight = int.Parse(txtHeight.Text.Trim());
                cap.Open();
            }
            catch (Exception ex)
            {
                lblStatus.Content = string.Format("打开摄像头异常{0} Index={1} ", ex.Message, cap._capIndex);
            }

            if(cap.IsOpened)
            {
                lblStatus.Content = string.Format("相机打开成功!");
            }
            else
            {
                lblStatus.Content = string.Format("相机打开失败!");
            }
            
        }


        private void btnGrabOne_Click(object sender, RoutedEventArgs e)
        {
            if (!cap.IsOpened)
            {
                lblStatus.Content = string.Format("请先打开相机!");
                return;
            }
               
            bool res = false;
            try
            {
                res = cap.GrabOneFrame();
            }
            catch (Exception ex)
            {
                lblStatus.Content = string.Format("打开摄像头异常{0} ", ex.Message);
            }
            if (res)
            {

                // 获取 BitmapSource
                var bitmapSource = GetBitmapSource(cap);

                if (bitmapSource != null)
                {
                    // 显示图像
                    MyImageControl.Source = bitmapSource;


                    string fileName = ".GrabOne.tif";
                    // 指定保存路径（运行目录下）
                    string filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
                    // 创建文件流
                    using (var fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
                    {
                        // 使用 PngBitmapEncoder 保存为 PNG 格式
                        var encoder = new TiffBitmapEncoder();
                        encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
                        encoder.Save(fileStream);
                    }

                    // 显示保存路径（可选）
                    lblStatus.Content = $"图像保存成功：{fileName}  分辨率 {bitmapSource.Width} * {bitmapSource.Height}";
                }

            }
        }

        bool isGrabimg = false;

        Thread thGrab = null;

        private void btnGrabContinue_Click(object sender, RoutedEventArgs e)
        {
            if (!isGrabimg)
            {
                if (!cap.IsOpened)
                {
                    lblStatus.Content = string.Format("请先打开相机!");
                    return;
                }
                btnGrabOne.IsEnabled = false;
                btnOpen.IsEnabled = false;
                btnGrabContinue.Content = "停止采集";
                isGrabimg = true;

                if (thGrab == null || !thGrab.IsAlive)
                {

                    thGrab = new Thread(doGrabFunc);
                    thGrab.Start();
                }
            }
            else
            {

                isGrabimg = false;

                if (thGrab != null)
                {
                    thGrab.Abort();
                    thGrab = null;
                }

                btnGrabContinue.Content = "连续采集";
                btnGrabOne.IsEnabled = true;
                btnOpen.IsEnabled = true;
            }

        }

        private void doGrabFunc()
        {
            isGrabimg = true;
            while (isGrabimg)
            {
                if (cap.GrabOneFrame())
                {

                    Dispatcher.Invoke((new Action(() =>
                    {
                        var bitmapSource = GetBitmapSource(cap);

                        if (bitmapSource != null)
                        {
                            // 显示图像
                            MyImageControl.Source = bitmapSource;
                        }

                    })));
                }
                Thread.Sleep(5);
            }
        }

        BitmapSource GetBitmapSource(MyVideo.MyVideoCapture _cap)
        {
            if (_cap.PtrData == IntPtr.Zero)
            {
                return null;
            }
            int width = _cap.ImWidth;
            int height = _cap.ImHeight;
            int channels = _cap.ImChannels;
            BitmapSource bitmapSource = null;
            if (channels == 1)
            {

                // 计算行对齐（WPF 要求 stride 是 4 的倍数）
                int rawStride = ((int)Math.Ceiling((double)width / 4)) * 4;

                // 创建字节数组以存储像素数据
                byte[] rawImage = new byte[rawStride * height];

                if (rawStride == width)
                {
                    // 如果无需补齐，对整个图像数据进行直接拷贝
                    Marshal.Copy(_cap.PtrData, rawImage, 0, rawImage.Length);
                }
                else
                {
                    // 如果行宽不足以满足对齐要求，需要逐行拷贝数据
                    IntPtr newPtr = _cap.PtrData;
                    for (int i = 0; i < height; ++i)
                    {
                        Marshal.Copy(newPtr, rawImage, i * rawStride, width);
                        newPtr = IntPtr.Add(newPtr, width); // 更新指针到下一行
                    }
                }

                // 创建灰度图像的 BitmapSource
                bitmapSource = BitmapSource.Create(width, height,
                    96, 96, PixelFormats.Gray8, null,
                    rawImage, rawStride);
            }
            else if (channels == 3) // 彩色图像
            {

                // 彩色图像的每行 stride 也需要是 4 的倍数
                int rawStride = ((int)Math.Ceiling((double)(width * 3) / 4)) * 4;

                // 创建字节数组以存储像素数据
                byte[] rawImage = new byte[rawStride * height];

                if (rawStride == width * 3)
                {
                    // 如果无需补齐，对整个图像数据进行直接拷贝
                    Marshal.Copy(_cap.PtrData, rawImage, 0, rawImage.Length);
                }
                else
                {
                    // 如果行宽不足以满足对齐要求，需要逐行拷贝数据
                    IntPtr newPtr = _cap.PtrData;
                    for (int i = 0; i < height; ++i)
                    {
                        Marshal.Copy(newPtr, rawImage, i * rawStride, width * 3);
                        newPtr = IntPtr.Add(newPtr, width * 3); // 更新指针到下一行
                    }
                }

                // 创建 RGB 彩色图像的 BitmapSource
                bitmapSource = BitmapSource.Create(width, height,
                    96, 96, PixelFormats.Bgr24, null,
                    rawImage, rawStride);

            }

            return bitmapSource;

        }

       
    }
}
